export async function* shellSort(array, compare, swap, set) {
    const n = array.length;
    
    // Start with a big gap, then reduce the gap
    for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
        
        // Do a gapped insertion sort for this gap size
        for (let i = gap; i < n; i++) {
            let temp = array[i];
            let j = i;
            
            // Shift earlier gap-sorted elements up until the correct location for array[i] is found
            while (j >= gap) {
                yield { type: 'compare', indices: [j - gap, j] };
                
                if (await compare(j - gap, j, array[j - gap], temp)) {
                    array[j] = array[j - gap];
                    yield { type: 'set', index: j, value: array[j] };
                    j -= gap;
                } else {
                    break;
                }
            }
            
            // Put temp (the original array[i]) in its correct location
            if (j !== i) {
                array[j] = temp;
                yield { type: 'set', index: j, value: array[j] };
            }
        }
    }
    
    yield { type: 'complete' };
}